package com.qianli.cashmama.trade.domain.factory.impl;

import com.alibaba.fastjson.JSON;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.xjd.user.client.enums.*;
import com.fqgj.xjd.user.client.request.*;
import com.fqgj.xjd.user.client.response.User;
import com.fqgj.xjd.user.client.response.UserAuthFaceRecognition;
import com.fqgj.xjd.user.client.response.UserBehaviorRegister;
import com.fqgj.xjd.user.client.response.UserSocialContact;
import com.qianli.cashmama.trade.client.trade.request.CreateAuditSuccessTradeRequest;
import com.qianli.cashmama.trade.client.trade.request.CreatePaySuccessTradeRequest;
import com.qianli.cashmama.trade.client.trade.request.CreateTradeRequest;
import com.qianli.cashmama.trade.client.trade.request.RepayTradeRequest;
import com.qianli.cashmama.trade.client.vo.DiscountListVO;
import com.qianli.cashmama.trade.common.dto.UserTradeSnapshotDto;
import com.qianli.cashmama.trade.common.enums.TradeClientTypeEnum;
import com.qianli.cashmama.trade.common.enums.TradeSignStatusEnum;
import com.qianli.cashmama.trade.common.enums.TradeTypeEnum;
import com.qianli.cashmama.trade.common.enums.UsageOfLoanEnum;
import com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum;
import com.qianli.cashmama.trade.common.exceptions.TradeException;
import com.qianli.cashmama.trade.common.utils.CalculatorUtils;
import com.qianli.cashmama.trade.common.utils.TradeConfigUtil;
import com.qianli.cashmama.trade.dao.TBillDao;
import com.qianli.cashmama.trade.dao.TTradeDao;
import com.qianli.cashmama.trade.dao.TTradeOpenOrderDao;
import com.qianli.cashmama.trade.domain.factory.TradeBaseDomainFactory;
import com.qianli.cashmama.trade.domain.model.TradeBank;
import com.qianli.cashmama.trade.domain.model.TradeBase;
import com.qianli.cashmama.trade.domain.model.TradeDiscount;
import com.qianli.cashmama.trade.domain.model.TradeRisk;
import com.qianli.cashmama.trade.entity.TBillEntity;
import com.qianli.cashmama.trade.entity.TTradeOpenOrderEntity;
import com.qianli.cashmama.trade.integration.product.ProductIntegrationService;
import com.qianli.cashmama.trade.integration.product.dto.ProductDto;
import com.qianli.cashmama.trade.integration.user.UserIntegrationService;
import com.qianli.cashmama.trade.integration.user.dto.UserBankDto;
import com.qianli.cashmama.trade.integration.user.dto.UserBaseInfoDto;
import com.qianli.cashmama.trade.integration.user.dto.UserTotalInfo;
import com.robert.vesta.util.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 构建交易base的工厂方法
 * Created by scrack on 2017/7/20.
 */
@Service
public class TradeBaseDomainFactoryImpl implements TradeBaseDomainFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(TradeBaseDomainFactoryImpl.class);

    @Autowired
    private ProductIntegrationService productIntegrationService;

    @Autowired
    private UserIntegrationService userIntegrationService;

    @Autowired
    private TTradeDao tTradeDao;

    @Autowired
    private TBillDao billDao;

    @Autowired
    private TradeConfigUtil tradeConfigUtil;

    @Autowired
    private TTradeOpenOrderDao tTradeOpenOrderDao;

    @Override
    public TradeBase composeTradeBase(CreateTradeRequest createTradeRequest) {
        TradeBase tradeBase = new TradeBase();
        try {
            ProductDto productDto = productIntegrationService.getProductInfoByCode(createTradeRequest.getProductCode());
            if (productDto == null || productDto.getStatus() != 1) {
                throw new IllegalArgumentException("Product unavailable");
            }

            UserBaseInfoDto userBaseInfoDto = userIntegrationService.getUserBaseInfoByUserCode(createTradeRequest.getUserCode(), productDto.getProductCategory());
            if (userBaseInfoDto == null) {
                LOGGER.error("==== 创建交易失败,用户信息不完整 ====,request:{}", JSON.toJSONString(createTradeRequest));
                throw new IllegalArgumentException("User status is not available");
            }

            if (StringUtils.isEmpty(userBaseInfoDto.getIdentityNo()) || StringUtils.isEmpty(userBaseInfoDto.getUserName())) {
                LOGGER.error("==== 创建交易失败,用户名或身份证号码为空 ====,request:{},userBaseInfoDto:{}", JSON.toJSONString(createTradeRequest), JSON.toJSONString(userBaseInfoDto));
                throw new IllegalArgumentException("The user name or id number is blank");
            }


            //step1:组装交易基本信息(顺序不可更改)
            fillTradeBase(tradeBase, createTradeRequest);

            //step2:构建风控信息
            fillTradeRisk(tradeBase, createTradeRequest.getUserCode());

            //step3:构建收付款相关信息
            fillTradeBank(tradeBase, userBaseInfoDto, createTradeRequest.getUserCode());

            //step4:构建优惠相关信息
            fillTradeDiscount(tradeBase, productDto, createTradeRequest.getDiscountList());

            //step5:组装交易金额相关信息
            fillTradeCapital(tradeBase, productDto);

            return tradeBase;
        } catch (com.qianli.cashmama.trade.common.exceptions.TradeException e) {
            LOGGER.error("创建交易失败1,request:" + JSON.toJSONString(createTradeRequest), e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("创建交易失败2,request:" + JSON.toJSONString(createTradeRequest), e);
            throw e;
        }
    }

    @Override
    public TradeBase composeAuditSuccessTradeBase(CreateAuditSuccessTradeRequest request, ProductDto productDto) {
        TradeBase tradeBase = new TradeBase();
        try {
            boolean isNewUser = tTradeDao.countByUserCode(request.getUserCode(), request.getCategoryCode()) == 0;
            tradeBase.setTradeNo(createTradeNo(request.getUserCode()))
                    .setProductCode(productDto.getProductCode())
                    .setUserCode(request.getUserCode())
                    .setCustomerCode(request.getUserCode())
                    .setChannelCode(request.getChannelCode())
                    .setTradeOrderStatus(com.qianli.cashmama.trade.common.enums.TradeStatusEnum.LOAN_WAITTING)
                    .setTradeSignStatus(TradeSignStatusEnum.INIT)
                    .setTradeAuditStatus(com.qianli.cashmama.trade.common.enums.TradeAuditStatusEnum.AUDIT_SUCCESS)
                    .setTradeAuditSubStatus(com.qianli.cashmama.trade.common.enums.TradeAuditSubStatusEnum.AUDIT_SUCCESS)
                    .setTradePayStatus(com.qianli.cashmama.trade.common.enums.TradePayStatusEnum.INIT)
                    .setClientType(TradeClientTypeEnum.H_5)
                    .setProductCategory(request.getCategoryCode())
                    .setNewUser(isNewUser)
                    .setUsageOfLoan(UsageOfLoanEnum.PERSONAL_DAILY_CONSUMPTION)
                    .setTradeOrderType(TradeTypeEnum.THIRD);

            //step3:构建收付款相关信息
            UserBankDto userBankDto = userIntegrationService.getUserBankSnapshotByUserCode(request.getUserCode());
            tradeBase.setTradeBank(new TradeBank()
                    .setBindType(userBankDto.getBindType())
                    .setIdentityNo("/")
                    .setBankName(userBankDto.getBankName())
                    .setBankType(userBankDto.getBankType())
                    .setTradeNo(tradeBase.getTradeNo())
                    .setCardNo(userBankDto.getCardNo())
                    .setSignMobile(userBankDto.getSignMobile())
                    .setUserName(request.getAcctName()));

            //step5:组装交易金额相关信息
            fillTradeCapital(tradeBase, productDto);
            tradeBase.setAuditDate(new Date());
            return tradeBase;
        } catch (TradeException e) {
            LOGGER.error("创建交易失败1,request:" + JSON.toJSONString(request), e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("创建交易失败2,request:" + JSON.toJSONString(request), e);
            throw new TradeException(TradeErrorCodeEnum.create_failed, e.getMessage());
        }
    }

    @Override
    public TradeBase composePaySuccessTradeBase(CreatePaySuccessTradeRequest request, ProductDto productDto) {
        TradeBase tradeBase = new TradeBase();
        try {
            boolean isNewUser = tTradeDao.countByUserCode(request.getUserCode(), request.getProductCategory()) == 0;
            tradeBase.setTradeNo(request.getTradeNo())
                    .setProductCode(productDto.getProductCode())
                    .setUserCode(request.getUserCode())
                    .setCustomerCode(request.getUserCode())
                    .setChannelCode(request.getChannelCode())
                    .setTradeOrderStatus(com.qianli.cashmama.trade.common.enums.TradeStatusEnum.REPAYMENT_WATTING)
                    .setTradeSignStatus(TradeSignStatusEnum.INIT)
                    .setTradeAuditStatus(com.qianli.cashmama.trade.common.enums.TradeAuditStatusEnum.AUDIT_SUCCESS)
                    .setTradeAuditSubStatus(com.qianli.cashmama.trade.common.enums.TradeAuditSubStatusEnum.AUDIT_SUCCESS)
                    .setTradePayStatus(com.qianli.cashmama.trade.common.enums.TradePayStatusEnum.PAY_SUCCESS)
                    .setClientType(TradeClientTypeEnum.H_5)
                    .setProductCategory(request.getProductCategory())
                    .setNewUser(isNewUser)
                    .setUsageOfLoan(request.getUsageOfLoan())
                    .setTradeOrderType(TradeTypeEnum.THIRD);

            //step3:构建收付款相关信息
            UserBankDto userBankDto = userIntegrationService.getUserBankSnapshotByUserCode(request.getUserCode());
            tradeBase.setTradeBank(new TradeBank()
                    .setBindType(userBankDto.getBindType())
                    .setIdentityNo("")
                    .setBankName(userBankDto.getBankName())
                    .setBankType(userBankDto.getBankType())
                    .setTradeNo(tradeBase.getTradeNo())
                    .setCardNo(userBankDto.getCardNo())
                    .setSignMobile(userBankDto.getSignMobile())
                    .setUserName(request.getUserName()));

            //step5:组装交易金额相关信息
            fillTradeCapital(tradeBase, productDto);
            tradeBase.setReceivedDate(request.getLoanTime());
            tradeBase.setAuditDate(new Date());

            TTradeOpenOrderEntity tTradeOpenOrderEntity = tTradeOpenOrderDao.getByTradeNo(tradeBase.getTradeNo());
            if(tTradeOpenOrderEntity != null){
                tradeBase.setCapitalCode(StringUtils.isNotEmpty(tTradeOpenOrderEntity.getFundCode()) ? Integer.valueOf(tTradeOpenOrderEntity.getFundCode()) : null);
                tradeBase.setPayNo(tTradeOpenOrderEntity.getPayNo());
            }
            return tradeBase;
        } catch (TradeException e) {
            LOGGER.error("创建交易失败1,request:" + JSON.toJSONString(request), e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("创建交易失败2,request:" + JSON.toJSONString(request), e);
            throw new TradeException(TradeErrorCodeEnum.create_failed, e.getMessage());
        }
    }

    /**
     * 组装构建交易（更新产品信息）
     *
     * @param tradeBase
     * @param productDto
     * @return
     */
    @Override
    public TradeBase convertTradeBase(TradeBase tradeBase, ProductDto productDto) {
        tradeBase.setProductCode(productDto.getProductCode());
        tradeBase.setProductCategory(productDto.getProductCategory());
        tradeBase.setBorrowTotalCapital(productDto.getBorrowTotalCapital());
        tradeBase.setReceivedTotalCapital(productDto.getReceivedTotalCapital());

        tradeBase.setTotalServiceFee(productDto.getTotalServiceFee());
        tradeBase.setBorrowRatio(productDto.getBorrowRatio());
        tradeBase.setTotalPeriod(productDto.getTotalPeriod());
        tradeBase.setPeriodLength(productDto.getPeriodLength());
        tradeBase.setOverdueServiceFee(productDto.getOverdueServiceFee());
        tradeBase.setOverdueRatio(productDto.getOverdueRatio());

        BigDecimal totalInterestFee = CalculatorUtils.calculateInterestFee(tradeBase.getBorrowTotalCapital(), tradeBase.getBorrowRatio(), tradeBase.getPeriodLength());
        //应还总金额
        BigDecimal repaymentTotalCapital = CalculatorUtils.createOrderRepaymentTotalCapital(tradeBase.getBorrowTotalCapital(), totalInterestFee);
        tradeBase.setRepaymentTotalCapital(repaymentTotalCapital);
        return tradeBase;
    }

    @Override
    public TradeBank composeTradeBank(RepayTradeRequest repayTradeRequest, TradeBank tradeBank) {
        tradeBank.setBankName(repayTradeRequest.getBankName())
                .setBankType(repayTradeRequest.getBankType())
                .setCardNo(repayTradeRequest.getCardNo());
        return tradeBank;
    }

    /**
     * 组装交易的基本信息
     *
     * @param tradeBase
     * @param createTradeRequest
     */
    private void fillTradeBase(TradeBase tradeBase, CreateTradeRequest createTradeRequest) {

        boolean isNewUser = tTradeDao.countByUserCode(createTradeRequest.getUserCode(), createTradeRequest.getProductCategory()) == 0;
        tradeBase.setTradeNo(createTradeNo(createTradeRequest.getUserCode()))
                .setProductCode(createTradeRequest.getProductCode())
                .setUserCode(createTradeRequest.getUserCode())
                .setCustomerCode(createTradeRequest.getUserCode())
                .setChannelCode(createTradeRequest.getChannelCode())
                .setTradeOrderStatus(com.qianli.cashmama.trade.common.enums.TradeStatusEnum.INIT)
                .setTradeSignStatus(TradeSignStatusEnum.INIT)
                .setTradeAuditStatus(com.qianli.cashmama.trade.common.enums.TradeAuditStatusEnum.INIT)
                .setTradeAuditSubStatus(com.qianli.cashmama.trade.common.enums.TradeAuditSubStatusEnum.INIT)
                .setTradePayStatus(com.qianli.cashmama.trade.common.enums.TradePayStatusEnum.INIT)
                .setClientType(createTradeRequest.getClientType())
                .setProductCategory(createTradeRequest.getProductCategory())
                .setNewUser(isNewUser)
                .setUsageOfLoan(createTradeRequest.getUsageOfLoan())
                .setTradeOrderType(createTradeRequest.getTradeType())
                .setExtraData(createTradeRequest.getExtraData())
                .setMerchantCode(createTradeRequest.getMerchantCode());
    }

    /**
     * 组装交易金额信息
     */
    private void fillTradeCapital(TradeBase tradeBase, ProductDto productDto) {
        tradeBase.setProductCategory(productDto.getProductCategory())
                .setBorrowTotalCapital(productDto.getBorrowTotalCapital())
                .setReceivedTotalCapital(productDto.getReceivedTotalCapital())
                .setDiscountTotalCapital(BigDecimal.ZERO)

                .setBorrowRatio(productDto.getBorrowRatio())
                .setServiceFeeRate(productDto.getServiceFeeRate())
                .setTotalServiceFee(productDto.getTotalServiceFee())

                .setTotalPeriod(productDto.getTotalPeriod())
                .setBorrowDuration(productDto.getBorrowDuration())
                .setPeriodLength(productDto.getPeriodLength())

                .setOverdueRatio(productDto.getOverdueRatio())
                .setOverdueServiceFee(productDto.getOverdueServiceFee());


        BigDecimal totalInterestFee = CalculatorUtils.calculateInterestFee(tradeBase.getBorrowTotalCapital(), tradeBase.getBorrowRatio(), tradeBase.getPeriodLength());
        //应还总金额
        BigDecimal repaymentTotalCapital = CalculatorUtils.createOrderRepaymentTotalCapital(tradeBase.getBorrowTotalCapital(), totalInterestFee);
        tradeBase.setRepaymentTotalCapital(repaymentTotalCapital);
    }

    /**
     * 组装交易快照信息
     */
    private void fillTradeRisk(TradeBase tradeBase, String userCode) {
        UserTradeSnapshotDto userTradeSnapshotDto = null;
        long start = System.currentTimeMillis();
        try {
            userTradeSnapshotDto = userIntegrationService.getUserTradeSnapshotInfoByUserCode(userCode, tradeBase.getProductCategory());
        } catch (com.qianli.cashmama.trade.common.exceptions.TradeException e) {
            LOGGER.error("fillTradeRiskError,组装交易快照信息失败", e);
            throw new com.qianli.cashmama.trade.common.exceptions.TradeException(com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum.fetch_user_snapshot_failed, e.getMessage());
        }

        List<TradeRisk> tradeRisks = new ArrayList<>();

        TradeRisk userSnap = new TradeRisk()
                .setTradeNo(tradeBase.getTradeNo())
                .setUserSnapshotInfoTypeEnum(com.qianli.cashmama.trade.common.enums.UserSnapshotInfoTypeEnum.USER_BASE_SNAP)
                .setValue(JSON.toJSONString(createUserTotalInfo(userTradeSnapshotDto)));
        if (userSnap != null) {
            tradeRisks.add(userSnap);
        }

        LOGGER.info("== 组装交易的快照信息消耗时间 ==,time:{}", System.currentTimeMillis() - start);
        tradeBase.setTradeRisks(tradeRisks);
    }

    /**
     * 组装交易收付款相关信息
     *
     * @param tradeBase
     */
    private void fillTradeBank(TradeBase tradeBase, UserBaseInfoDto userBaseInfoDto, String userCode) {
        UserBankDto userBankDto = userIntegrationService.getUserBankSnapshotByUserCode(userCode);
        tradeBase.setTradeBank(new TradeBank()
                .setBindType(userBankDto.getBindType())
                .setIdentityNo(userBaseInfoDto.getIdentityNo())
                .setBankName(userBankDto.getBankName())
                .setBankType(userBankDto.getBankType())
                .setTradeNo(tradeBase.getTradeNo())
                .setCardNo(userBankDto.getCardNo())
                .setSignMobile(userBankDto.getSignMobile())
                .setUserName(userBaseInfoDto.getUserName()));
    }

    /**
     * 组装优惠相关信息
     *
     * @param tradeBase
     * @param discountList
     */
    private void fillTradeDiscount(TradeBase tradeBase, ProductDto productDto, List<DiscountListVO> discountList) {
        if (CollectionUtils.isEmpty(discountList)) {
            return;
        }

        List<TradeDiscount> tradeDiscountList = new ArrayList<>(discountList.size());
        BigDecimal totalDiscountCapital = BigDecimal.valueOf(0);
        for (DiscountListVO discountListVO : discountList) {
//            CouponVO couponVO = sdzzCouponService.getUserCouponById(Long.parseLong(discountListVO.getDiscountCode()));
//            if (!couponVO.getCouponStatus().equals(CouponStatusEnums.New.getValue())) {
//                throw new TradeException(TradeErrorCodeEnum.trade_not_exist, "优惠券不可用");
//            }

            TradeDiscount tradeDiscount = new TradeDiscount()
                    .setDiscountCode(discountListVO.getDiscountCode())
                    .setDiscountType(com.qianli.cashmama.trade.common.enums.TradeDiscountTypeEnum.COUPON)
                    .setTradeNo(tradeBase.getTradeNo())
                    .setStatus(com.qianli.cashmama.trade.common.enums.TradeDiscountStatusEnum.NOT_VERIFIED);
            tradeDiscountList.add(tradeDiscount);
        }

        tradeBase.setDiscountTotalCapital(totalDiscountCapital);
        tradeBase.setTradeDiscountList(tradeDiscountList);
    }


    private String createTradeNo(String userCode) {
        try {
            String tradeNo = IdUtils.genId() + "DC";
            LOGGER.info("== 创建交易 ==,tradeNo:{}", tradeNo);
            return tradeNo;
        } catch (com.qianli.cashmama.trade.common.exceptions.TradeException e) {
            LOGGER.error("==生成tradeNo异常==,userCode:{},e", userCode, e);
            throw new com.qianli.cashmama.trade.common.exceptions.TradeException(com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum.create_failed, "生成tradeNo异常");
        }
    }


    public static UserTotalInfo createUserTotalInfo(UserTradeSnapshotDto userTradeSnapshotDto) {

        try {
            User user = userTradeSnapshotDto.getUserInfo().getUser();
            UserEmergencyContact userEmergencyContact = userTradeSnapshotDto.getUserSocialContact().getUserEmergencyContact();
            UserBase userBase = userTradeSnapshotDto.getUserInfo().getUserBase();
            UserSocialContact userSocialContact = userTradeSnapshotDto.getUserSocialContact();

            UserAuthFaceRecognition userAuthFaceRecognition = null;
            if (CollectionUtils.isNotEmpty(userTradeSnapshotDto.getUserauthFaceRecognitionList())) {
                userAuthFaceRecognition = userTradeSnapshotDto.getUserauthFaceRecognitionList().get(0);
            }

            UserWork userWork = userTradeSnapshotDto.getUserInfo().getUserWork();
            UserResident userResident = userTradeSnapshotDto.getUserInfo().getUserResident();
            UserContact userContact = userTradeSnapshotDto.getUserInfo().getUserContact();
            UserBehaviorRegister userBehaviorRegister = userTradeSnapshotDto.getUserBehaviorRegister();
            ShumeiDevice shumeiDevice = userTradeSnapshotDto.getShumeiDevice();


            UserTotalInfo userTotalInfo = new UserTotalInfo()
                    .setUserName(user.getName())
                    .setMobile(user.getMobile())
                    .setIdentityNo(user.getIdentityNo())

                    .setUserFirstName(userBase.getFirstName())
                    .setUserMiddleName(userBase.getMiddleName())
                    .setUserLastName(userBase.getLastName())
                    .setUserEmail(userBase.getEmail())
                    .setUserFatherName(userBase.getFatherName())
                    .setUserMotherName(userBase.getMotherName())

                    .setUserDob(userBase.getBirthday())
                    .setUserUsage(UsagesEnum.getEnumByType(userBase.getUsages()) == null ? "" : UsagesEnum.getEnumByType(userBase.getUsages()).getDesc())
                    .setGender(UserGenderEnum.getEnumByCode(userBase.getGender()) == null ? "" : UserGenderEnum.getEnumByCode(userBase.getGender()).toString())

                    .setFriendEmergenceContactName(userEmergencyContact.getUserFriendContact().getName())
                    .setFriendEmergenceContactInputName(userEmergencyContact.getUserFriendContact().getContactName())
                    .setFriendEmergenceContactRelation(userEmergencyContact.getUserFriendContact().getUserContactFriendTypeEnum().getDesc())
                    .setFriendEmergenceContactBindNum(1)
                    .setFriendEmergenceContactMobile(userEmergencyContact.getUserFriendContact().getMobile())

                    .setFamilyEmergenceContactName(userEmergencyContact.getUserFamilyContact().getName())
                    .setFamilyEmergenceContactInputName(userEmergencyContact.getUserFamilyContact().getContactName())
                    .setFamilyEmergenceContactRelation(userEmergencyContact.getUserFamilyContact().getUserContactFamilyTypeEnum().getDesc())
                    .setFamilyEmergenceContactBindNum(1)
                    .setFamilyEmergenceContactMobile(userEmergencyContact.getUserFamilyContact().getMobile())

                    .setContactUrl(userSocialContact.getDeviceContact())
                    //无运营商信息
                    //.setCarrierUrl(userSocialContact.getCarrier().getUrl())
                    //.setEducationStatus(UserEducationEnum.getEnumByType(userBase.getEducation()).getDesc())
                    .setUserAadhaarInfo(userTradeSnapshotDto.getUserAadhaarInfo())
                    .setUserPanInfo(userTradeSnapshotDto.getUserPanInfo())
                    .setUserKycDocumentInfo(userTradeSnapshotDto.getUserKycDocumentInfo());

            if (userBase.getMarriedStatus() != null) {
                UserMarriageEnum enumByType = UserMarriageEnum.getEnumByType(userBase.getMarriedStatus());
                if (enumByType != null) {
                    userTotalInfo.setMarriageStatus(enumByType.getDesc());
                }
            }

            if (userContact != null) {
                userTotalInfo.setQq(userContact == null ? "" : userContact.getQq());
            }

            if (userResident != null) {
                userTotalInfo.setLiveProvince(userResident.getProvince())
                        .setLiveCity(userResident.getCity())
                        .setLiveAddress(userResident.getAddress())
                        .setUserPinCode(userResident.getPinCode())
                        .setPermanentState(userResident.getPermanentState())
                        .setPermanentCity(userResident.getPermanentCity())
                        .setPermanentAddress(userResident.getPermanentAddress())
                        .setPermanentPinCode(userResident.getPermanentPinCode())
                ;
                if (userResident.getDuration() != null) {
                    UserLiveDurationEnum enumByType = UserLiveDurationEnum.getEnumByType(userResident.getDuration());
                    if (enumByType != null) {
                        userTotalInfo.setLiveDuration(enumByType.getDesc());
                    }
                }
            }

            userTotalInfo.setBirthPlace(userAuthFaceRecognition == null ? "暂无" : userAuthFaceRecognition.getAddress())
                    .setIdentityFrontUrl(userAuthFaceRecognition == null ? "" : userAuthFaceRecognition.getFrontUrl())
                    .setIdentityBackUrl(userAuthFaceRecognition == null ? "" : userAuthFaceRecognition.getBackUrl())
                    .setLivePictureUrl(userAuthFaceRecognition == null ? "" : userAuthFaceRecognition.getFaceEnvUrl())
                    .setUserHandIdentityUrl(userAuthFaceRecognition == null ? "" : userAuthFaceRecognition.getFaceEnvUrl())
                    .setShuMeiInfoUrl(shumeiDevice == null ? "" : shumeiDevice.getFingerprintInfo())
                    .setUserCode(user.getUserCode())
                    .setUserPhotoPassed(userAuthFaceRecognition == null ? 0 : userAuthFaceRecognition.getPassed())
                    .setRegisterDate(user.getGmtCreate())
                    .setClientId(userBehaviorRegister.getClientId());
            if (userBehaviorRegister.getPlatform() != null) {
                PlatformEnum enumByType = PlatformEnum.getEnumByType(userBehaviorRegister.getPlatform());
                if (enumByType != null) {
                    userTotalInfo.setPlatform(enumByType.getDesc());
                }
            }

            userTotalInfo.setVersion(userBehaviorRegister.getVersion())
                    .setChannelCode(userBehaviorRegister.getChannel())
                    .setAppCode(userBehaviorRegister.getAppCode());

            if (userWork != null) {
                userTotalInfo.setUserCompanyName(userWork.getCompanyName())
                        .setUserCompanyAddress(userWork.getProvince() + ", " + userWork.getCity())
                        .setUserCompanyDetailAddress(userWork.getAddress())
                        .setUserCompanyPhone(userWork.getPhone())
                        .setUserCompanyPinCode(userWork.getOfficePinCode())
                        .setUserCompanyFromWhen(userWork.getFromWhen());
                if (userWork.getCareerType() != null) {
                    UserCareerEnum enumByType = UserCareerEnum.getEnumByType(userWork.getCareerType());
                    if (enumByType != null) {
                        userTotalInfo.setUserCareer(enumByType.getDesc());
                    }
                }

                if (userWork.getSalary() != null) {
                    UserSalaryEnum enumByType = UserSalaryEnum.getEnumByType(userWork.getSalary());
                    if (enumByType != null) {
                        userTotalInfo.setUserSalary(enumByType.getDesc());
                    }
                }
                userTotalInfo.setUserSalaryDay(userWork.getPayDay());
            }

            return userTotalInfo;

        } catch (Exception e) {
            LOGGER.error("== 组装用户基本信息快照出错 ==,userTradeSnapshotDto:" + JSON.toJSONString(userTradeSnapshotDto), e);
//            return null;
            throw new TradeException(TradeErrorCodeEnum.fetch_user_snapshot_failed);
        }
    }
}
